<?php 

/**
 * A geocoder adapter for the Geocoder.us API
 *
 * @category Noginn
 * @package Noginn_Geocoder
 */
class Noginn_Geocoder_Adapter_GeocoderUs extends Noginn_Geocoder_Adapter_Abstract
{
    /** Base Geocoder.us API URI */
    const SERVICE_URI = 'http://geocoder.us/service/rest';

    /**
     * The HTTP client to use for API requests
     *
     * @var Zend_Http_Client
     */
    protected $_httpClient;
    
    /**
     * Constructor
     *
     * @param array|Zend_Config $config 
     * @return void
     */
    public function __construct($config = array())
    {
        iconv_set_encoding('output_encoding', 'UTF-8');
        iconv_set_encoding('input_encoding', 'UTF-8');
        iconv_set_encoding('internal_encoding', 'UTF-8');
    }
    
    /**
     * Return the HTTP client. 
     * If not set then create a new instance of Zend_Http_Client.
     *
     * @return Zend_Http_Client
     */
    public function getHttpClient()
    {
        if (is_null($this->_httpClient)) {
            $this->_httpClient = new Zend_Http_Client(self::SERVICE_URI);
        }

        return $this->_httpClient;
    }
    
    /**
     * Specify the Zend_Http_Client object to use
     *
     * @param Zend_Http_Client $httpClient 
     * @return void
     */
    public function setHttpClient(Zend_Http_Client $httpClient)
    {
        $httpClient->setUri(self::SERVICE_URI);
        $this->_httpClient = $httpClient;
    }
    
    /**
     * Geocode the address
     *
     * @param string|array $address 
     * @return Noginn_Geocoder_LocationList
     */
    public function geocode($address)
    {
        $httpClient = $this->getHttpClient();
        $httpClient->resetParameters();
        $httpClient->setParameterGet('address', $this->_buildQuery($address));
        $response = $httpClient->request('GET');
        
        // Check for HTTP client request errors
        if ($response->isError()) {
            throw new Zend_Exception('An error occurred sending the geocode request. Status code: ' . $response->getStatus());
        }
        
        $responseBody = $response->getBody();
        if ($responseBody == "couldn't find this address! sorry") {
            throw new Zend_Exception('No corresponding geographic location could be found for the specified address.');
        }
        
        $xml = new SimpleXMLElement($responseBody);
        
        var_dump($responseBody);
        
        // Parse the result set
        $locationList = new Noginn_Geocoder_LocationList();
        foreach ($xml->Point as $result)
        {
            $location = new Noginn_Geocoder_Location();
            $location->latitude = (float) $result->lat;
            $location->longitude = (float) $result->long;
            $location->address = (string) $result->description;
            
            $locationList->addLocation($location);
        }
        
        return $locationList;
    }
}